package com.middlegroup.subjectpay.service.impl;

import com.middlegroup.common.enums.ServiceType;
import com.middlegroup.common.exception.ErrorMsg;
import com.middlegroup.common.model.TransResult;
import com.middlegroup.subjectpay.dto.TransRequest;
import com.middlegroup.subjectpay.entity.*;
import com.middlegroup.subjectpay.service.*;
import com.middlegroup.subjectpay.service.empty.EmptyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Created by pc on 2019/1/14.
 */
@Service
@Slf4j
public class ProtocolPayServiceImpl implements ProtocolPayService {
    @Resource
    private CardBinService cardBinService;
    @Resource
    private SubjectInBillsService subjectInBillsService;
    @Resource
    private EmptyService emptyService;
    @Resource
    private UcfpayService ucfpayService;
    @Resource
    private ChangpayService changpayService;
    @Resource
    private ThirdProtocolBindCardService thirdProtocolBindCardService;
    @Resource
    private ThirdProtocolApplyService thirdProtocolApplyService;
    @Resource
    private KjtpayService kjtpayService;

    @Override
    public TransResult protocolPay(TransRequest request) {
        if (StringUtils.isBlank(request.getServiceType())){
            request.setServiceType(ServiceType.PROTOCOL_PAY.name());
        }

        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        //校验参数
        if (StringUtils.isBlank(request.getMerchantBillNo())){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.EMPTY_MERCHANTBILLNO);
            return transResult;
        }
        if (StringUtils.isBlank(request.getBillNo())){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.EMPTY_BILLNO);
            return transResult;
        }
        if (null == request.getChannelCode()){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.EMPTY_CHANNELCODE);
            return transResult;
        }
        if (StringUtils.isBlank(request.getSubjectCode())){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.EMPTY_SUBJECTCODE);
            return transResult;
        }
        if (null == request.getStep()){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.EMPTY_PAYSTAP);
            return transResult;
        }
        if (2==request.getStep().intValue() && StringUtils.isBlank(request.getSmsCode())){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.EMPTY_SMSCODE);
            return transResult;
        }

        if(StringUtils.isBlank(request.getProtocolNo())){
           //查询当前渠道的协议号
            ThirdProtocolBindCard thirdProtocolBindCardFind=new ThirdProtocolBindCard();
            thirdProtocolBindCardFind.setSubjectCode(request.getSubjectCode());
            thirdProtocolBindCardFind.setChannelCode(request.getChannelCode().getCode());
            thirdProtocolBindCardFind.setCardNo(request.getCardNo());
            thirdProtocolBindCardFind.setName(request.getName());
//            thirdProtocolBindCardFind.setPhone(request.getPhone());
            thirdProtocolBindCardFind.setIdCard(request.getIdCard());
            thirdProtocolBindCardFind.setStatus(1);
            ThirdProtocolBindCard thirdProtocolBindCard=thirdProtocolBindCardService.getLastOne(thirdProtocolBindCardFind);
            if(null!=thirdProtocolBindCard && StringUtils.isNotBlank(thirdProtocolBindCard.getProtocolNo())){
                request.setProtocolNo(thirdProtocolBindCard.getProtocolNo());
            }
        }

        SubjectInBills subjectInBills=null;
        ThirdProtocolApply thirdProtocolApply=null;
        if(1==request.getStep().intValue()){
            if(StringUtils.isNotBlank(request.getProtocolNo())){
                //第一步插入inBills表(第一步，且是签约过的协议支付)
                subjectInBills=new SubjectInBills();
                subjectInBills.setSubjectCode(request.getSubjectCode());
                subjectInBills.setMerchantBillNo(request.getMerchantBillNo());
                subjectInBills.setBillNo(request.getBillNo());
                subjectInBills.setChannelCode(request.getChannelCode().getCode());
                subjectInBills.setServiceType(request.getServiceType());
                subjectInBills.setAmount(request.getAmount());
                subjectInBills.setStatus(0);

                boolean rt = false;
                try {
                    rt = subjectInBillsService.insert(subjectInBills);
                }catch (Exception e){
                    log.error("插入主体端入款订单表(t_subject_in_bills)失败:"+request.getBillNo(),e);
                }
                if (!rt) {
                    //插入失败
                    transResult.setTransStatus(2);
                    transResult.setMsg("插入主体端出款订单表(t_subject_in_bills)失败:"+request.getBillNo());
                    return transResult;
                }
            }else {
                //第一步插入协议支付申请表(第一步，且是未签约过的协议支付，即畅捷协议支付那种首次支付成功就算协议绑卡成功)
                thirdProtocolApply=new ThirdProtocolApply();
                thirdProtocolApply.setSubjectCode(request.getSubjectCode());
                thirdProtocolApply.setChannelCode(request.getChannelCode().getCode());
                thirdProtocolApply.setMerchantBillNo(request.getMerchantBillNo());
                thirdProtocolApply.setBillNo(request.getBillNo());
                thirdProtocolApply.setCardNo(request.getCardNo());
                thirdProtocolApply.setPhone(request.getPhone());
                thirdProtocolApply.setName(request.getName());
                thirdProtocolApply.setIdCard(request.getIdCard());
                thirdProtocolApply.setStatus(0);
                boolean rt = false;
                try {
                    rt = thirdProtocolApplyService.insert(thirdProtocolApply);
                }catch (Exception e){
                    log.error("插入主体端协议支付申请表(t_third_protocol_apply)失败:"+request.getBillNo(),e);
                }

                if (!rt) {
                    //插入失败
                    transResult.setTransStatus(2);
                    transResult.setMsg("插入主体端协议支付申请表(t_third_protocol_apply)失败:"+request.getBillNo());
                    return transResult;
                }
            }

        }else if(2==request.getStep().intValue()){
            //支付确认，插入billNo表
            subjectInBills=new SubjectInBills();
            subjectInBills.setSubjectCode(request.getSubjectCode());
            subjectInBills.setMerchantBillNo(request.getMerchantBillNo());
            subjectInBills.setBillNo(request.getBillNo());
            subjectInBills.setChannelCode(request.getChannelCode().getCode());
            subjectInBills.setServiceType(request.getServiceType());
            subjectInBills.setAmount(request.getAmount());
            subjectInBills.setStatus(0);

            boolean rt = false;
            try {
                rt = subjectInBillsService.insert(subjectInBills);
            }catch (Exception e){
                log.error("插入主体端入款订单表(t_subject_in_bills)失败:"+request.getBillNo(),e);
            }

            if (!rt) {
                //插入失败
                transResult.setTransStatus(2);
                transResult.setMsg("插入主体端入款订单表(t_subject_in_bills)失败:"+request.getBillNo());
                return transResult;
            }

        }else if(5==request.getStep().intValue()){
            //重发短信验证码
            SubjectInBills subjectInBillsFind=new SubjectInBills();
            subjectInBillsFind.setSubjectCode(request.getSubjectCode());
            subjectInBillsFind.setMerchantBillNo(request.getMerchantBillNo());
            subjectInBillsFind.setBillNo(request.getBillNo());
            subjectInBillsFind.setChannelCode(request.getChannelCode().getCode());
            subjectInBills=subjectInBillsService.getLastOneInBills(subjectInBillsFind);
            boolean flag=null==subjectInBills || (null!=subjectInBills && 1==subjectInBills.getStatus());
            if(flag){
                transResult.setMsg(ErrorMsg.BILLSNOTFOUND_OR_STATUSFAIL);
                transResult.setTransStatus(2);
                return transResult;
            }
        }

        //获得bankCode
        CardBin cardBin = cardBinService.getBankInfoByCardNo(request.getCardNo());
        if (null == cardBin){
            subjectInBills.setStatus(2);
            subjectInBillsService.updateById(subjectInBills);

            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.UNKNOWN_CARD_NO);
            return transResult;
        }

        request.setCardBin(cardBin.getBankCode());


        /**
         * 此处一定要注意，调用第三方渠道接口必须返回TransResult，不可为空，且保证异常在接口中已处理
         */
        switch (request.getChannelCode()){
            case CH3333331:
                try{
                    //TODO 调用第三方通道接口：先锋协议支付
                    if(request.getStep().intValue()==1){
                        //第一步发送短信验证码 或者直接扣款
                        if(StringUtils.isNotBlank(request.getProtocolNo())){
                            //有协议号，直接扣款
                            request.setServiceType(ServiceType.PROTOCOL_SECONDDEDUCT.name());
                            transResult=ucfpayService.protocolPay(request);
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                        }else {
                            //异常情况，该渠道要先签约
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                            transResult.setTransStatus(2);
                            transResult.setMsg("异常情况，该渠道要先签约！");
                        }
                    }else {
                        transResult.setStep(request.getStep());
                        //没有下一步
                        transResult.setNextStep(null);
                        //流程结束
                        transResult.setEnd(1);
                        transResult.setTransStatus(2);
                        transResult.setMsg("未找到相应step!");
                    }
                }catch (Exception e){
                    log.error("CH3333331第三方通道畅捷交易接口调用失败"+request.getBillNo(),e);
                }
                break;

            case CH3333332:
                try{
                    //TODO 调用第三方通道接口：快捷通协议支付
                    if(request.getStep().intValue()==1){
                        //第一步发送短信验证码 或者直接扣款
                        if(StringUtils.isNotBlank(request.getProtocolNo())){
                            //有协议号，直接扣款
                            request.setServiceType(ServiceType.PROTOCOL_SECONDDEDUCT.name());
                            transResult=kjtpayService.protocolPay(request);
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                        }else {
                            //异常情况，该渠道要先签约
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                            transResult.setTransStatus(2);
                            transResult.setMsg("异常情况，该渠道要先签约！");
                        }
                    }else {
                        transResult.setStep(request.getStep());
                        //没有下一步
                        transResult.setNextStep(null);
                        //流程结束
                        transResult.setEnd(1);
                        transResult.setTransStatus(2);
                        transResult.setMsg("未找到相应step!");
                    }
                }catch (Exception e){
                    log.error("CH3333332第三方通道交易接口调用失败"+request.getBillNo(),e);
                }
                break;

            case CH3333333:
                try{
                    //TODO 调用第三方通道接口：畅捷协议支付
                    if(request.getStep().intValue()==1){
                        //第一步发送短信验证码 或者直接扣款
                        if(StringUtils.isNotBlank(request.getProtocolNo())){
                            //有协议号，直接扣款
                            request.setServiceType(ServiceType.PROTOCOL_SECONDDEDUCT.name());
                            transResult=changpayService.secondProtocolPay(request);
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                        }else {
                            //无协议号，需要发送短信验证码
                            request.setServiceType(ServiceType.PROTOCOL_FIRSTDEDUCTAPPLY.name());
                            transResult=changpayService.firstProtocolPayApply(request);
                            transResult.setStep(request.getStep());
                            //下一步确认验证码
                            transResult.setNextStep(2);
                            //流程未结束
                            transResult.setEnd(0);
                        }
                    }else if(request.getStep().intValue()==2){
                        //第二步确认扣款（要有验证码）
                        request.setServiceType(ServiceType.PROTOCOL_FIRSTDEDUCTCONFIRM.name());
                        transResult=changpayService.firstProtocolPayConfirm(request);
                        transResult.setStep(request.getStep());
                        //没有下一步
                        transResult.setNextStep(null);
                        //流程结束
                        transResult.setEnd(1);
                    }else if(request.getStep().intValue()==5){
                        //重发短信验证码
                        request.setServiceType(ServiceType.PROTOCOL_FIRSTDEDUCTRESENDSMS.name());
                        transResult=changpayService.firstProtocolPayReSendSMS(request);
                        transResult.setStep(request.getStep());
                        //下一步确认验证码
                        transResult.setNextStep(2);
                        //流程未结束
                        transResult.setEnd(0);
                    }else {
                        transResult.setStep(request.getStep());
                        //没有下一步
                        transResult.setNextStep(null);
                        //流程结束
                        transResult.setEnd(1);
                        transResult.setTransStatus(2);
                        transResult.setMsg("未找到相应step!");
                    }
                }catch (Exception e){
                    log.error("CH3333333第三方通道交易接口调用失败"+request.getBillNo(),e);
                }
                break;

            case EMPTY0000003:
                try{
                    //TODO 调用第三方通道接口：模拟渠道
                    if(request.getStep().intValue()==1){
                        //第一步发送短信验证码 或者直接扣款
                        if(StringUtils.isNotBlank(request.getProtocolNo())){
                            //有协议号，直接扣款
                            request.setServiceType(ServiceType.PROTOCOL_SECONDDEDUCT.name());
                            transResult=emptyService.protocolPay(request);
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                        }else {
                            //异常情况，该渠道要先签约
                            transResult.setStep(request.getStep());
                            //没有下一步
                            transResult.setNextStep(null);
                            //流程结束
                            transResult.setEnd(1);
                            transResult.setTransStatus(2);
                            transResult.setMsg("异常情况，该渠道要先签约！");
                        }
                    }else {
                        transResult.setStep(request.getStep());
                        //没有下一步
                        transResult.setNextStep(null);
                        //流程结束
                        transResult.setEnd(1);
                        transResult.setTransStatus(2);
                        transResult.setMsg("未找到相应step!");
                    }
                }catch (Exception e){
                    log.error("EMPTY0000003第三方通道交易接口调用失败"+request.getBillNo(),e);
                }
                break;
            default:
                transResult.setStep(request.getStep());
                //没有下一步
                transResult.setNextStep(null);
                //流程结束
                transResult.setEnd(1);
                transResult.setTransStatus(2);
                transResult.setMsg("未找到相应channelCode!");
        }

        //是否更新bills表状态(1:流程结束且状态确定 2：协议支付申请的时候失败)
        if(null!=subjectInBills){
            boolean ifUpdateBillStatusOne = null != transResult && null != transResult.getTransStatus() && (transResult.getTransStatus().intValue()==1 || transResult.getTransStatus().intValue()==2) && null!=transResult.getEnd() && transResult.getEnd().intValue()==1;
            boolean ifUpdateBillStatusTwo = null != transResult && null != transResult.getTransStatus() && transResult.getTransStatus().intValue()==2 && StringUtils.equals(request.getServiceType(),ServiceType.PROTOCOL_FIRSTDEDUCTAPPLY.name());
            if ((ifUpdateBillStatusOne || ifUpdateBillStatusTwo)){
                subjectInBills.setStatus(transResult.getTransStatus());
                subjectInBillsService.updateById(subjectInBills);
            }
        }

        //是否更新t_third_protocol_apply表的状态
        if(null!=thirdProtocolApply){
            //是失败的情况
            boolean ifUpdateApplyStatusOne = null != transResult && null != transResult.getTransStatus() && transResult.getTransStatus().intValue()==2;
            //且是没有协议号的第一步，类似畅捷协议支付模式
            boolean ifUpdateApplyStatusTwo = 1==request.getStep().intValue() && StringUtils.isBlank(request.getProtocolNo());
            if ((ifUpdateApplyStatusOne && ifUpdateApplyStatusTwo)){
                //这里只更新协议支付请求失败的状态，成功的时候在支付成功记录协议号的时候更改（绑卡确认，协议支付查询，协议支付结果回调 三个地方）
                thirdProtocolApply.setStatus(transResult.getTransStatus());
                thirdProtocolApplyService.updateById(thirdProtocolApply);
            }
        }
        return transResult;
    }
}
